#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {
	STOP=0,		//任务停止 
	READY,		//任务就绪
	RUNNING,	//任务运行中
	AWAIT,		//任务等待 
}TaskCotrol; 
//ceshi

typedef void (* qfunc )(void);
typedef struct {
	int TaskPriority;			//任务优先级,1-255,255是最高优先级 
	int TaskNum; 				//任务编号
	int RunTime;				//任务运行时间片，毫秒单位
	int	RunAwait;				//任务等待时间片，毫秒单位,暂未实现
	int	RunCont;				//任务运行次数,达到运行次数后会自动清除任务
	TaskCotrol TaskSta;			//任务状态 
	qfunc nfunc;				//任务函数指针 
}Task_List;

Task_List task_t[20];

void TaskInit(void){
	memset(&task_t,0,sizeof(task_t));	
}

/*********************************
TaskAdd：任务添加函数 
fname:任务函数名 
tp:任务优先级
rt:任务运行时间片 
ra：任务等待多长时间后才出就绪状态 
rc: 任务运行次数
ts: 初始化时任务状态
成功返回任务编号，失败返回0 
**********************************/
int TaskAdd(qfunc fname,int tp,int rt,int ra,int rc,TaskCotrol ts)
{
	int i=0;
	for(i=0;i<sizeof(task_t);i++){
		if(!task_t[i].nfunc){
			task_t[i].nfunc=fname;
			task_t[i].TaskPriority=tp;
			task_t[i].TaskNum=i+1;
			task_t[i].RunTime=rt;
			task_t[i].RunAwait=ra;
			task_t[i].RunCont=rc;
			task_t[i].TaskSta=ts;
			return task_t[i].TaskNum; 
		}
	} 
	return 0;
}
/*************************************
TaskFuncNameDel删除任务函数
fname：任务名
成功删除返回1，失败返回0 
*************************************/
int TaskFuncNameDel(qfunc fname) 
{
	int i=0;
	for(i=0;i<sizeof(task_t);i++){	
		if(task_t[i].nfunc==fname){
			task_t[i].nfunc=0;
			task_t[i].TaskNum=0;
			return 1;
		}
	}
	return 0;	
}

/*************************************
TaskFuncNumDel删除任务函数
tnum：任务编号 
成功删除返回1，失败返回0 
*************************************/
int TaskFuncNumDel(int tnum) 
{
	if(task_t[tnum-1].nfunc){
		task_t[tnum-1].nfunc=0;
		task_t[tnum-1].TaskNum=0;		
	}else{
		return 0;	
	} 		
}
/*************************************
TaskNameEdit任务名修改函数 
OldName：旧任务名
NewName: 新任务名 
成功删除返回1，失败返回0 
*************************************/
int TaskNameEdit(qfunc OldName,qfunc NewName){
	int i=0;
	if(OldName && NewName){
		for(i=0;i<sizeof(task_t);i++){
			if(task_t[i].nfunc == OldName){
				task_t[i].nfunc=NewName;
				return 1;
			}
		}	
	}	
	return 0;
} 

/*************************************
TaskStaEdit任务任务状态修改函数
fname:任务名
NewSta:新的任务状态
返回被修改的任务数
*************************************/
int TaskStaEdit(qfunc Name,TaskCotrol NewSta){
	int i=0;
	if(Name){
		for(i=0;i<TaskNumeCunt;i++){
			if(task_t[i].nfunc == Name){
				task_t[i].TaskSta=NewSta;
				return i+1;
			}
		}	
	}	
	return 0;
} 




/*************************************
TaskPriorityEdit任务优先级修改函数 
name：需要修改优先级的任务名
tn	: 需要修改优先级的任务编号
tp: 新的优先级
TaskPriorityEdit将找到任务名相同或者任务编号
相同的任务指定新的优先级 

成功被修改的任务数量，失败返回0 
*************************************/
int TaskPriorityEdit(qfunc name,int tn,int tp){
	int i=0,econt=0;
	if(name || tn){
		for(i=0;i<sizeof(task_t);i++){
			if(task_t[i].nfunc == name){
				task_t[i].TaskPriority= tp;
					++econt;
			}
			if(task_t[i].TaskNum == tn){
				task_t[i].TaskNum= tp;
					++econt;
			}
		}	
	}	
	return econt;
}
/*********************************************




**********************************************/
/***********************************
TaskSwitch任务调度函数
找到优先级最高并处于就绪的 
运行 
************************************/
void TaskSwitch(void){
	int Pri=0,i=0;
	static int tcnt=0,tnum=0,rtime=0; 
	static unsigned char TimeCntSwirth=0;	//任务调度状态
	if(tcnt || rtime ||TimeCntSwirth)goto ONCE_RUNING;
//	printf("task_t[i]\n");
	for(i=0;i<sizeof(task_t);i++){	
		if(task_t[i].nfunc && task_t[i].TaskSta==READY){	//查找就绪的任务的任务 
			if(task_t[i].TaskPriority>Pri){					//查找优秀级最高的任务 
				Pri=task_t[i].TaskPriority;
				tnum=task_t[i].TaskNum;	
			//	printf("task_t[i].TaskNum  %d\n",i);
			}
		}	
	}
	if(!tnum){	//如果没有就绪的任务，就查找有没有等待中度任务 
		for(i=0;i<sizeof(task_t);i++){	
			if(task_t[i].nfunc && task_t[i].TaskSta==AWAIT){	//查找等待中度任务 
				task_t[i].TaskSta=READY;	//将任务设为就绪状态 
			}	
		}
		return;				
	}
	if(task_t[tnum-1].RunTime){
		//如果设置任务时间片就按时间片运行任务 
		rtime=task_t[tnum-1].RunTime;
		TimeCntSwirth=1;		
	}else if(task_t[tnum-1].RunCont){
		//如果没有设置任务时间片就加载任务运行次数	
		tcnt=task_t[tnum-1].RunCont;
		TimeCntSwirth=2;	
	}else{
		//如果时间片和运行次数都没有当前任务调度状态设置为零
		TimeCntSwirth=0;
		return;	
	}
ONCE_RUNING:	 
	switch(TimeCntSwirth){
		case 1://按时间片运行 
			while(rtime){
				--rtime;
				task_t[tnum-1].nfunc();
				if(!rtime){	//任务运行时间到达后的执行动作
					TimeCntSwirth=0;	//当前任务调度状态设置为零
					task_t[tnum-1].TaskSta=AWAIT;//将任务设为等待 
					tnum=0;//清除当前运行的任务编号 	
				}
			} 
			break;
		case 2:	//按次数运行 
			if(tcnt){
				--tcnt;
				task_t[tnum-1].nfunc();
			}else{	//任务运行次数到达后的执行动作
				TimeCntSwirth=0;	//当前任务调度状态设置为零
				task_t[tnum-1].nfunc=0;	  //清除任务
				task_t[tnum-1].TaskNum=0; //清除任务列表里的任务编号
				tnum=0;	//清除当前运行的任务编号 				
			}
			break;
	}


}
void abc(void)
{
	printf("adc\n");
 } 

void abcd(void)
{
	printf("adcd\n");
 } 
void abcdE(void)
{
	printf("adcdE\n");
 } 

void abcdEGH(void)
{
	printf("adcdEGH\n");
 } 

int main(int argc, char *argv[]) {
	int i=0;
	TaskInit();
	for(i=0;i<10;i++){
		TaskSwitch();	
	}
	TaskAdd(abc,251,0,0,6,READY);		//按次数运行，次数到了以后会自动从任务列表清除 
	TaskAdd(abcd,250,0,0,3,READY);	//按次数运行，次数到了以后会自动从任务列表清除  
	TaskAdd(abcd,250,10,0,0,READY);		//按时间片运行，不会自动从务列表清除 
	TaskAdd(abc,251,5,0,0,READY);		//按时间片运行，不会自动从务列表清除 
	TaskAdd(abcdE,1,10,0,0,READY);		//按时间片运行，不会自动从务列表清除 
	TaskAdd(abcdEGH,3,2,0,0,READY);		//按时间片运行，不会自动从务列表清除 
	for(i=0;i<1000;i++){
		TaskSwitch();	
	}	
	return 0;
}
